package com.hlkj.baojin.utils.bean;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.FeatureDescriptor;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author liu-zhong-xin
 * @createDate 2018/7/10 0010
 */
public class CopyUtil {
    /**
     * 一个list转换 class类型 并且创建一个新的集合
     *
     * @param a
     * @param c
     * @param <T>
     * @return
     */
    public static <T> List<T> copy(List<?> a, Class<T> c) {
        List<T> list = new ArrayList<>();
        for (Object o : a) {
            try {
                T t = c.newInstance();
                BeanUtils.copyProperties(o, t);
                list.add(t);
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
    /**
     * 一个DTO  并且创建一个model
     *
     * @param a
     * @param c
     * @param <T>
     * @return
     */
    public static <T> T copy(Object a, Class<T> c) {
        if(a==null){
            return null;
        }
        T t = null;
        try {
            t = c.newInstance();
            BeanUtils.copyProperties(a, t);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return t;
    }

    public static <T> T deepClone(T obj) {
        ByteArrayOutputStream bo = null;
        ObjectOutputStream oo = null;
        ByteArrayInputStream bi = null;
        ObjectInputStream oi = null;
        try {
            // 将对象写到流里
            bo = new ByteArrayOutputStream();
            oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            // 从流里读出来
            bi = new ByteArrayInputStream(bo.toByteArray());
            oi = new ObjectInputStream(bi);
            return (T) oi.readObject();
        } catch (IOException | ClassNotFoundException e){
            e.printStackTrace();
        } finally {
            if(bo != null) {
                try {
                    bo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(oo != null) {
                try {
                    oo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bi != null) {
                try {
                    bi.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(oi != null) {
                try {
                    oi.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return null;
    }

    /**
     * spring copyProperties:过滤空值
     *
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper wrappedSource = new BeanWrapperImpl(source);
        return Stream.of(wrappedSource.getPropertyDescriptors())
                .map(FeatureDescriptor::getName)
                .filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null)
                .toArray(String[]::new);
    }
}
